package com.rgp.apipassenger.service.impl;

import com.rgp.internalcommon.common.RedisPrefixConstant;
import com.rgp.apipassenger.feign.ServicePassengerUserClient;
import com.rgp.apipassenger.service.VerificationCodeService;
import com.rgp.internalcommon.common.CommonStatusEnum;
import com.rgp.internalcommon.common.VerificationCodeConstant;
import com.rgp.internalcommon.common.PassengerInfoConstant;
import com.rgp.internalcommon.common.TokenDurationTimeConstant;
import com.rgp.internalcommon.dto.UserInfoDto;
import com.rgp.internalcommon.dto.ResponseResult;
import com.rgp.apipassenger.feign.ServiceVerificationCodeClient;
import com.rgp.internalcommon.response.NumberCodeResponse;
import com.rgp.internalcommon.response.TokenResponse;
import com.rgp.internalcommon.utils.JwtUtils;
import com.rgp.internalcommon.utils.NameGenerateUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;

/**
 * @author nhp
 * @version 1.0
 * @description TODO
 * @date 2024-04-10 20:49
 */
@Service
public class VerificationCodeServiceImpl implements VerificationCodeService {

    @Autowired
    private ServiceVerificationCodeClient codeClient;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ServicePassengerUserClient servicePassengerUserClient;

    public String getVerificationCode(String passengerPhone){

        //1.调用远程微服务生成验证码
//        System.out.println("调用远程微服务生成验证码");
        ResponseResult<NumberCodeResponse> result = codeClient.generateNumberCode(VerificationCodeConstant.VERIFICATION_CODE_SIZE);
        Integer numberCode = ((NumberCodeResponse) result.getData()).getNumberCode();
        String code = String.valueOf(numberCode);

        //2.验证码存入redis
//        System.out.println("验证码存入redis");
        String verificationCodeKey = getVerificationcodePrefix() + passengerPhone;
        stringRedisTemplate.opsForValue().set(verificationCodeKey,String.valueOf(code),VerificationCodeConstant.VERIFICATION_CODE_REDIS_TIME, TimeUnit.MINUTES);

        //3.借助第三方API发送验证码短信
        System.out.println("借助第三方API发送验证码短信");

        //4.返回验证码
        return code;
    }

    public ResponseResult checkVerificationCode(String passengerPhone,String numberCode){
        //1.校验验证码与redis中的验证码是否一致，并校验是否超时
        String verificationCodeKey = getVerificationcodePrefix() + passengerPhone;
        String codeRedis = stringRedisTemplate.opsForValue().get(verificationCodeKey);
        if (StringUtils.isEmpty(codeRedis)){
            return ResponseResult.fail(CommonStatusEnum.VERIFICATIONCODE_TIMEOUT_ERROR);
        }else if(!codeRedis.equals(numberCode)){
            return ResponseResult.fail(CommonStatusEnum.VERIFICATIONCODE_ERROR);
        }

        //2.查询该手机号对应的用户是否存在
        ResponseResult<UserInfoDto> responseResult = servicePassengerUserClient.getPassengerByPhoneNumber(passengerPhone);
        UserInfoDto userInfoDto = responseResult.getData();

        //3.用户不存在，则完成用户的注册
        if (userInfoDto == null){
            userInfoDto = new UserInfoDto();
            userInfoDto.setUserPhone(passengerPhone);
            userInfoDto.setUserName(NameGenerateUtils.getRandomName());
            userInfoDto.setPassengerGender(PassengerInfoConstant.PASSENGER_GENDER_DEFAULT);
            servicePassengerUserClient.registPassenger(userInfoDto);
        }

        //4.用户已存在，则给用户颁发token,并将token存入到redis中
//        System.out.println("用户已存在，则给用户颁发token");
        //生成accessToken
        String accessToken = JwtUtils.tokenGenerate(userInfoDto, TokenDurationTimeConstant.ACCESS_TOKEN_VALID_MINUTES);
        stringRedisTemplate.opsForValue().set(RedisPrefixConstant.PASSENGER_ACCESSTOKEN_PREFIX + passengerPhone, accessToken,
                TokenDurationTimeConstant.ACCESS_TOKEN_VALID_MINUTES, TimeUnit.MINUTES);
        //生成RefreshToken
        String refreshToken = JwtUtils.tokenGenerate(userInfoDto, TokenDurationTimeConstant.REFRESH_TOKEN_VALID_MINUTES);
        stringRedisTemplate.opsForValue().set(RedisPrefixConstant.PASSENGER_REFRESHTOKEN_PREFIX + passengerPhone, refreshToken,
                TokenDurationTimeConstant.REFRESH_TOKEN_VALID_MINUTES, TimeUnit.MINUTES);

        //5.返回双token
        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(accessToken);
        tokenResponse.setRefreshToken(refreshToken);
        return ResponseResult.success(tokenResponse);
    }

    private String getVerificationcodePrefix(){
        return RedisPrefixConstant.PASSENGER_VERIFICATIONCODE_PREFIX;
    }
}